#include <ESP8266WiFi.h>
#include <PubSubClient.h>
 
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "ZXC_4G";
const char* password = "ZXCzxc123...";
const char* mqttServer = "192.168.1.105";
 
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // 设置板上LED引脚为输出模式
  digitalWrite(LED_BUILTIN, HIGH);  // 启动后关闭板上LED
  Serial.begin(115200);               // 启动串口通讯
  
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
  
  // 连接WiFi
  connectWifi();
  
  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  // 设置MQTT订阅回调函数
  mqttClient.setCallback(receiveCallback);
 
  // 连接MQTT服务器
  connectMQTTserver();
}
 
void loop() {
  if (mqttClient.connected()) { // 如果开发板成功连接服务器
    mqttClient.loop();          // 处理信息以及心跳
    digitalWrite(LED_BUILTIN, LOW);  // 成功连接服务器后板上LED
  } else {                      // 如果开发板未能成功连接服务器
    connectMQTTserver();        // 则尝试连接服务器
    digitalWrite(LED_BUILTIN, HIGH);  // 连接服务器失败关闭板上LED
  }
}
 
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID（避免与其它ESP8266的客户端ID重名）
  String clientId = "zxc_esp8266";
 
  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address:");
    Serial.println(mqttServer);
    Serial.println("ClientId: ");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}
 
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  char temp[9] = {0x00,0x00,0xff,0x01,0x00,0x3a,0x98,0x07,0xd0};
  //取出最后俩字节数据
  uint16_t val_ori = 0;
  val_ori += payload[4];
  val_ori <<= 8;
  val_ori += payload[5];
  uint8_t dir = 0;
  if(val_ori >= 0x4f00 && val_ori <= 0x51ee)
  {
    val_ori = 0;
    temp[4] = 0x00;
  }else
  if(val_ori > 0x51ee)
  {
    val_ori -= 20480;
    temp[4] = 0x00;
  }else
  {
    val_ori = 20480 - val_ori;
    temp[4] = 0x01;
  }
  if(val_ori != 0)
    val_ori -= 103;//左端和0对齐
  double val_temp = val_ori / 1.86;
  uint16_t val_after = (uint16_t)val_temp;
  //限幅
  if(val_after > 11000) val_after = 11000;
  //拆分数据
  uint8_t data1 = val_after >> 8;
  uint8_t data2 = val_after << 8 >> 8;
  //发送帧头
  if(1)
  {
    Serial.print((char)temp[0]);
    Serial.print((char)temp[1]);
    Serial.print((char)temp[2]);
  }
  //使能位
  Serial.print((char)temp[3]);
  //发送方向位
  Serial.print((char)temp[4]);
  //发送角度数据位
  Serial.print((char)data1);
  Serial.print((char)data2);
  Serial.print((char)temp[5]);//力量数据位
  Serial.print((char)temp[6]);//力量数据位
  Serial.print((char)temp[7]);//速度数据位
  Serial.print((char)temp[8]);//速度数据位
}
 
// 订阅指定主题
void subscribeTopic(){
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  if(mqttClient.subscribe("logic")){
    Serial.println("Subscrib Topic Successfully!");
  } else {
    Serial.print("Subscribe Fail...");
  }
}
 
// ESP8266连接wifi
void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
}